﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace Js.ComponentModel
{
    /// <summary>
    /// Property 데이터 변화를 알려주는 클래스입니다.
    /// </summary>
    public class NotificationObject : INotifyPropertyChanged
    {
        #region Event Handler

        /// <summary>
        /// 속성 값이 변경되면 발생합니다.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Event Handler

        #region Method

        /// <summary>
        /// Property 변화가 생겼음을 Binding Target에 알립니다.
        /// </summary>
        /// <typeparam name="TSource">Func의 반환 형식입니다.</typeparam>
        /// <param name="action">TSource 형식을 반환하는 Func의 식 트리입니다.</param>
        /// <example>
        /// public class ExampleClass : NOtificationObject
        /// {
        ///     private int _exampleInt;
        ///     public int ExampleProperty
        ///     {
        ///         get { return _exampleInt; }
        ///         set
        ///         {
        ///             _exampleInt = value;
        ///             RaisePropertyChanged(() => ExampleProperty);
        ///         }
        ///     }
        /// }
        /// </example>
        protected void RaisePropertyChanged<TSource>(Expression<Func<TSource>> action)
        {
            RaisePropertyChanged(GetPropertyName(action));
        }

        private string GetPropertyName<TSource>(Expression<Func<TSource>> action)
        {
            return (action.Body as MemberExpression).Member.Name;
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion Method
    }
}